import logging
import os
import sys

from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QFileDialog, QTableWidgetItem, QMessageBox, QTableWidget
from typing import List

from data.defines import RouteInfo
from gcs_views.ui_route_setting import Ui_RouteSetPad
from gcs_views.ui_takeoff_checklist import Ui_takeoff_checklist


def _check_and_get_route(table_route: QTableWidget):
    row = table_route.rowCount()
    route_list = []
    if row == 0:
        QMessageBox.information(None, 'info', '请先添加航路点', QMessageBox.Ok)
        return route_list, row
    for i in range(row):
        p = RouteInfo()
        for j in range(8):
            item = table_route.item(i, j)
            if item is None:
                QMessageBox.information(None, 'info', '数据不完整！', QMessageBox.Ok)
                return [], 0
            else:
                value_str = item.text().strip()
                if len(value_str) == 0:
                    QMessageBox.information(None, 'info', '数据不完整！', QMessageBox.Ok)
                    return [], 0
        try:
            # TODO:在结构体中新增航线号元素
            # TODO:根据航点号读取值设置p.no
            p.no = i + 1
            p.lon = float(table_route.item(i, 2).text().strip())
            p.lat = float(table_route.item(i, 3).text().strip())
            p.alt = int(table_route.item(i, 4).text().strip())
            p.spd = float(table_route.item(i, 5).text().strip())
            p.status = int(table_route.item(i, 6).text().strip())
            route_list.append(p)
        except ValueError as e:
            QMessageBox.information(None, 'info', '第 %d 行 数据格式错误！' % p.no, QMessageBox.Ok)
            logging.error(repr(e))
            return route_list, i
    return route_list, row


def _check_and_save_route(table_route: QTableWidget):
    filename, filetype = QFileDialog.getSaveFileName(None, 'save file', os.getcwd())
    if len(filename) == 0:
        return

    route_str = "Dot,Lon,Lat,Alt,Vxd\n"
    total = table_route.rowCount()
    for i in range(total):
        s = str(i + 1)
        s += ',' + table_route.item(i, 2).text().strip()
        s += ',' + table_route.item(i, 3).text().strip()
        s += ',' + table_route.item(i, 4).text().strip()
        str_vxd_cmd = table_route.item(i, 6).text().strip()
        str_vxd_param = table_route.item(i, 7).text().strip()
        vxd = int(str_vxd_cmd) << 12 + int(str_vxd_param)
        s += ',' + str(vxd)
        # for j in range(4):
        #     item = self.online_tab_editing.item(i, j)
        #     if item is None:
        #         s += ','
        #     else:
        #         s += ',' + item.text().strip()
        route_str += s + '\n'
    try:
        with open(filename, 'w') as f:
            f.write(route_str)
            f.close()
    except Exception as e:
        QMessageBox.information(None, 'info', '导出写入失败！' + repr(e), QMessageBox.Ok)


def _check_and_load_route(table_route: QTableWidget):
    filename, filetype = QFileDialog.getOpenFileName(None,
                                                     "选取文件",
                                                     os.getcwd(),
                                                     "CSV Files (*.csv)")
    if len(filename) == 0:
        return

    try:
        # 读取文件
        with open(filename, 'r') as fr:
            data_arr = fr.read().strip().split('\n')
            fr.close()
            # print(data_arr)
            del data_arr[0]
            table_len = table_route.rowCount()
            for i in range(table_len):
                table_route.removeRow(0)

            table_route.setRowCount(len(data_arr))
            for idx, line in enumerate(data_arr):
                route_item = line.split(',')
                if len(route_item) != 5:
                    logging.error("错误的航线格式")
                    return
                str_dot = route_item[0]
                str_lon = route_item[1]
                str_lat = route_item[2]
                str_alt = route_item[3]
                str_vxd = route_item[4]
                str_spd = '0'
                str_line_idx = '1'
                vxd_cmd = (int(str_vxd) & 0xF000) >> 12
                vxd_param = (int(str_vxd) & 0x000F)
                str_vxd_cmd = str(vxd_cmd)
                str_vxd_param = str(vxd_param)

                table_route.setItem(idx, 0, QTableWidgetItem(str_line_idx))
                table_route.setItem(idx, 1, QTableWidgetItem(str_dot))
                table_route.setItem(idx, 2, QTableWidgetItem(str_lon))
                table_route.setItem(idx, 3, QTableWidgetItem(str_lat))
                table_route.setItem(idx, 4, QTableWidgetItem(str_alt))
                table_route.setItem(idx, 5, QTableWidgetItem(str_spd))
                table_route.setItem(idx, 6, QTableWidgetItem(str_vxd_cmd))
                table_route.setItem(idx, 7, QTableWidgetItem(str_vxd_param))
            # if len(route_item) >= 5:
            #     for j in range(1, 5):
            #         self.online_tab_editing.setItem(idx, j - 1, QTableWidgetItem(route_item[j]))
    except Exception as e:
        logging.error(repr(e))
        QMessageBox.information(None, "警告", "航线文件加载失败！" + repr(e),
                                QMessageBox.Yes, QMessageBox.Yes)


def _table_add_dot(table_route: QTableWidget):
    idx = table_route.currentRow()
    total = table_route.rowCount()
    if idx == -1:
        table_route.setRowCount(total + 1)
    else:
        table_route.insertRow(idx + 1)


def _table_del_dot(table_route: QTableWidget):
    idx = table_route.currentRow()
    if idx != -1:
        table_route.removeRow(idx)


def _table_clear(table_route: QTableWidget):
    table_len = table_route.rowCount()
    for i in range(table_len):
        table_route.removeRow(0)


def _table_load_route(table_route: QTableWidget, route_list: List[RouteInfo], dot_num: int):
    # print("_table_load_route")
    # print(dot_num)
    # 清除表格显示内容
    table_len = table_route.rowCount()
    for i in range(table_len):
        table_route.removeRow(0)
    if len(route_list) != dot_num:
        QMessageBox.information(None, "警告", "加载航线格式错误！",
                                QMessageBox.Yes, QMessageBox.Yes)
        return
    table_route.setRowCount(dot_num)
    for idx in range(dot_num):
        str_line_idx = str(1)
        str_dot = str(route_list[idx].no)
        str_lon = str(route_list[idx].lon)
        str_lat = str(route_list[idx].lat)
        str_alt = str(route_list[idx].alt)
        str_spd = str(route_list[idx].spd)
        str_vxd_cmd = str(route_list[idx].status)
        str_vxd_param = str(route_list[idx].parm)
        table_route.setItem(idx, 0, QTableWidgetItem(str_line_idx))
        table_route.setItem(idx, 1, QTableWidgetItem(str_dot))
        table_route.setItem(idx, 2, QTableWidgetItem(str_lon))
        table_route.setItem(idx, 3, QTableWidgetItem(str_lat))
        table_route.setItem(idx, 4, QTableWidgetItem(str_alt))
        table_route.setItem(idx, 5, QTableWidgetItem(str_spd))
        table_route.setItem(idx, 6, QTableWidgetItem(str_vxd_cmd))
        table_route.setItem(idx, 7, QTableWidgetItem(str_vxd_param))


class RouteSetPad(QWidget, Ui_RouteSetPad):
    online_sig_upload_start = pyqtSignal(list, int)  # 开始在线航线装订 本地发出，外部接收
    online_sig_show2map = pyqtSignal(list, int)  # 将在线航线显示到地图 本地发出，外部接收
    online_sig_load_from_map = pyqtSignal()  # 从地图加载在线航线信号，本地发出，外部接收
    online_sig_upload_enable = pyqtSignal()
    online_sig_upload_disable = pyqtSignal()
    online_sig_load_finished = pyqtSignal(list, int)  # 外部发送，本地接收
    online_sig_download_finished = pyqtSignal(list, int)
    online_sig_get_config = pyqtSignal()  # 发送航线查询命令 本地发出
    online_sig_delete_config = pyqtSignal()  # 发送在线航线删除命令

    route_sig_upload_start = pyqtSignal(list, int)  # 开始航线装订 本地发出，外部接收
    route_sig_show2map = pyqtSignal(list, int)  # 将航线显示到地图 本地发出，外部接收
    route_sig_load_from_map = pyqtSignal()  # 从地图加载在航线信号，本地发出，外部接收
    route_sig_load_finished = pyqtSignal(list, int)  # 外部发送，本地接收
    route_sig_download_finished = pyqtSignal(list, int)
    route_sig_get_config = pyqtSignal(int)  # 发送航线查询命令 本地发出
    route_sig_delete_config = pyqtSignal(int)  # 发送航线删除命令

    def __init__(self):
        super(RouteSetPad, self).__init__()
        # self.setWindowTitle("子窗口")
        self.setupUi(self)
        self.gui_init()

    def gui_init(self):
        self.online_btn_readfile.clicked.connect(self.online_readfile)
        self.online_btn_save2file.clicked.connect(self.online_save2file)
        self.online_btn_add_dot.clicked.connect(self.online_add_dot)
        self.online_btn_del_dot.clicked.connect(self.online_del_dot)
        self.online_btn_upload.clicked.connect(self.online_upload)
        self.online_btn_clear_input.clicked.connect(self.online_clear_input)
        self.online_btn_show2map.clicked.connect(self.online_show2map)
        self.online_btn_load_from_map.clicked.connect(self.online_load_from_map)
        self.online_btn_query.clicked.connect(self.online_query)
        self.online_btn_delete.clicked.connect(self.online_delete)
        self.online_btn_show2map2.clicked.connect(self.online_show2map2)
        self.online_btn_clear_result.clicked.connect(self.online_clear_result)
        self.online_btn_save2file2.clicked.connect(self.online_save2file2)
        self.online_btn_upload_enable.clicked.connect(lambda: self.online_sig_upload_enable.emit())
        self.online_btn_upload_disable.clicked.connect(lambda: self.online_sig_upload_disable.emit())

        self.route_btn_save2file.clicked.connect(self.route_save2file)
        self.route_btn_read_file.clicked.connect(self.route_read_file)
        self.route_btn_add_dot.clicked.connect(self.route_add_dot)
        self.route_btn_del_dot.clicked.connect(self.route_del_dot)
        self.route_btn_upload.clicked.connect(self.route_upload)
        self.route_btn_clear_Input.clicked.connect(self.route_clear_Input)
        self.route_btn_show2map.clicked.connect(self.route_show2map)
        self.route_btn_load_from_map.clicked.connect(self.route_load_from_map)
        self.route_btn_query.clicked.connect(self.route_query)
        self.route_btn_delete.clicked.connect(self.route_delete)
        self.route_btn_clear_result.clicked.connect(self.route_clear_result)
        self.route_btn_show2map2.clicked.connect(self.route_show2map2)
        self.route_btn_save2file2.clicked.connect(self.route_save2file2)

        self.online_clear_input()
        self.online_clear_result()
        self.online_sig_load_finished.connect(self.online_load_data_show)
        self.online_sig_download_finished.connect(self.online_download_data_show)

        self.route_clear_Input()
        self.route_clear_result()
        self.route_sig_load_finished.connect(self.route_load_data_show)
        self.route_sig_download_finished.connect(self.route_download_data_show)

    def route_save2file(self):
        _check_and_save_route(self.route_tab_editing)

    def route_read_file(self):
        _check_and_load_route(self.route_tab_editing)

    def route_add_dot(self):
        _table_add_dot(self.route_tab_editing)

    def route_del_dot(self):
        _table_del_dot(self.route_tab_editing)

    def route_upload(self):
        route_list, dot_num = _check_and_get_route(self.route_tab_editing)
        self.route_sig_upload_start.emit(route_list, dot_num)

    def route_clear_Input(self):
        _table_clear(self.route_tab_editing)

    def route_show2map(self):
        route_list, dot_num = _check_and_get_route(self.route_tab_editing)
        self.route_sig_show2map.emit(route_list, dot_num)

    def route_load_from_map(self):
        self.route_sig_load_from_map.emit()

    def route_download_data_show(self, route_list, dot_num):
        _table_load_route(self.route_tab_editing, route_list, dot_num)

    def route_load_data_show(self, route_list, dot_num):
        _table_load_route(self.route_tab_result, route_list, dot_num)
        # print("route_load_data_show")
        # print(route_list)
        # print(dot_num)

    def route_query(self):
        self.route_sig_get_config.emit(int(self.route_edit_line_idx.value()))

    def route_delete(self):
        self.route_sig_delete_config.emit(self.route_edit_line_idx.value())

    def route_clear_result(self):
        _table_clear(self.route_tab_result)

    def route_show2map2(self):
        route_list, dot_num = _check_and_get_route(self.route_tab_result)
        self.route_sig_show2map.emit(route_list, dot_num)

    def route_save2file2(self):
        _check_and_save_route(self.route_tab_result)

    def online_clear_input(self):
        _table_clear(self.online_tab_editing)

    def online_readfile(self):
        _check_and_load_route(self.online_tab_editing)

    def online_save2file(self):
        _check_and_save_route(self.online_tab_editing)

    def online_add_dot(self):
        _table_add_dot(self.online_tab_editing)

    def online_del_dot(self):
        _table_del_dot(self.online_tab_editing)

    def online_upload(self):
        route_list, dot_num = _check_and_get_route(self.online_tab_editing)
        self.online_sig_upload_start.emit(route_list, dot_num)

    def online_show2map(self):
        route_list, dot_num = _check_and_get_route(self.online_tab_editing)
        self.online_sig_show2map.emit(route_list, dot_num)

    def online_load_from_map(self):
        self.online_sig_load_from_map.emit()

    def online_download_data_show(self, route_list, dot_num):
        _table_load_route(self.online_tab_result, route_list, dot_num)

    def online_load_data_show(self, route_list, dot_num):
        _table_load_route(self.online_tab_editing, route_list, dot_num)
        # print("online_load_data_show")
        # print(route_list)
        # print(dot_num)

    def online_query(self):  # 查询在线航线
        self.online_sig_get_config.emit()

    def online_delete(self):
        self.online_sig_delete_config.emit()

    def online_show2map2(self):
        route_list, dot_num = _check_and_get_route(self.online_tab_result)
        self.online_sig_show2map.emit(route_list, dot_num)

    def online_clear_result(self):
        _table_clear(self.online_tab_result)

    def online_save2file2(self):
        _check_and_save_route(self.online_tab_result)


if __name__ == '__main__':
    # 启动地面站主界面
    app = QtWidgets.QApplication(sys.argv)
    gcs_main_window = QtWidgets.QMainWindow()
    ui = RouteSetPad()
    ui.setupUi(gcs_main_window)
    ui.gui_init()
    gcs_main_window.show()  # 显示窗口

    sys.exit(app.exec_())
